package org.groupg.practice;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.timelimiter.TimeLimiter;
import io.github.resilience4j.timelimiter.TimeLimiterConfig;

import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NetworkRequestExample {

    public static void main(String[] args) throws Exception {
        // 配置断路器
        CircuitBreakerConfig cbConfig = CircuitBreakerConfig.custom()
                .failureRateThreshold(50)
                .minimumNumberOfCalls(5)
                .waitDurationInOpenState(Duration.ofSeconds(10))
                .build();
        CircuitBreaker circuitBreaker = CircuitBreaker.of("networkBreaker", cbConfig);

        // 配置超时（1秒）
        TimeLimiterConfig timeLimiterConfig = TimeLimiterConfig.custom()
                .timeoutDuration(Duration.ofSeconds(1))
                .build();
        TimeLimiter timeLimiter = TimeLimiter.of(timeLimiterConfig);

        RemoteService service = new RemoteService();
        ExecutorService executor = Executors.newCachedThreadPool();

        // 修复：使用Callable替代Supplier
        Callable<String> callable = () -> {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(
                    service::fetchData,
                    executor
            );
            return future.get();
        };

        // 组合弹性模块
        Callable<String> decoratedCallable = TimeLimiter.decorateFutureSupplier(
                timeLimiter,
                () -> CompletableFuture.supplyAsync(service::fetchData, executor)
        );

        // 添加断路器保护
        decoratedCallable = CircuitBreaker.decorateCallable(circuitBreaker, decoratedCallable);

        // 执行10次调用
        for (int i = 0; i < 10; i++) {
            try {
                String result = decoratedCallable.call();
                System.out.println("Call " + i + ": " + result);
            } catch (Exception e) {
                System.err.println("Call " + i + " failed: " + e.getMessage());
            }
            Thread.sleep(300); // 模拟请求间隔
        }

        executor.shutdown();
    }

    // 模拟网络服务
    static class RemoteService {
        String fetchData() {
            double rand = Math.random();
            if (rand > 0.7) {
                throw new RuntimeException("Server error");
            } else if (rand > 0.4) {
                // 模拟慢响应
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException ignored) {
                }
            }
            return "Remote data";
        }
    }
}